package com.ptc.ims.client.presenter;

import java.util.List;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.HasWidgets;
import com.ptc.ims.client.InventoryServiceAsync;
import com.ptc.ims.client.event.CancelCreateEditProductEvent;
import com.ptc.ims.client.util.CustomDialogBox;
import com.ptc.ims.client.util.Validator;
import com.ptc.ims.shared.Product;

public class ProductPresenter 
extends AbstractPresenter 
implements Presenter 
{
	public static final String PAGE_CREATE = "create";
	public static final String PAGE_EDIT = "edit";
	
	public final Display view;
	
	public ProductPresenter(InventoryServiceAsync inventoryService,	HandlerManager handlerManager, Display view) 
	{
		super(inventoryService, handlerManager);
		this.view = view;
	}
	
	@Override
	public void go(HasWidgets container)
	{	
		super.go(container);
		if (view.getId() != null)
		{
			fetchProduct();
		}		
	}

	@Override
	public void bind() 
	{
		view.getAddUpdateButton().addClickHandler(new ClickHandler() {			
			@Override
			public void onClick(ClickEvent event) 
			{
				Validator validator = new Validator();
				List<String> errors = validator.validate(view.getProductName().getValue(), view.getPrice().getValue());
				if (errors.isEmpty())
				{
					addUpdateProduct();
				}
				else
				{
					String errorMessage = "<ul>";
					for (String error : errors)
					{
						errorMessage += "<li>" + error + "</li>";
					}
					errorMessage += "</ul>";
					createSimpleDialog("OK", "Validation Error", errorMessage).show();
				}
			}
		});
		view.getCancelButton().addClickHandler(new ClickHandler() {			
			@Override
			public void onClick(ClickEvent event) {
				getHandlerManager().fireEvent(new CancelCreateEditProductEvent());
			}
		});
		
	}
	
	@Override
	public DisplayView getView()
	{		
		return view;
	}
	
	public void fetchProduct()
	{
		AsyncCallback<Product> callBack = new AsyncCallback<Product>()
		{
			@Override
			public void onFailure(Throwable caught)
			{
				createSimpleDialog("OK", "Fetch Error", "An error occured during retrieving records").show();
			}

			@Override
			public void onSuccess(Product result) 
			{
				if (result != null)
				{
					view.getPrice().setValue(result.getPrice().toString());
					view.getProductName().setValue(result.getName());
				}
				else
				{
					final CustomDialogBox dialogBox = new CustomDialogBox();
					dialogBox.addButton("OK", new ClickHandler() {						
						@Override
						public void onClick(ClickEvent event) 
						{							
							dialogBox.hide();
							getHandlerManager().fireEvent(new CancelCreateEditProductEvent());
						}
					});
					dialogBox.addTitle("Item Not Found").addMessage("Kindly check the URL");
					dialogBox.build().show();
				}
				
			}		
			
		};
		getInventoryService().fetchProduct(view.getId(), callBack);
	}
	
	public void addUpdateProduct()
	{
		
		Product product = new Product(view.getId(), view.getProductName().getValue(), Double.valueOf(view.getPrice().getValue()));			
		if (product.getId() != null)
		{
			AsyncCallback<Boolean> updateCallback = new AsyncCallback<Boolean>() {
				@Override
				public void onFailure(Throwable caught)
				{
					createSimpleDialog("OK", "Server Error", "An error occured during update.").show();
				}

				@Override
				public void onSuccess(Boolean result) 
				{
					createSimpleDialog("OK", "Update Successful", "").show();									
				}

			};
			getInventoryService().modifyProduct(product, updateCallback);
		}
		else
		{
			AsyncCallback<String> addCallback = new AsyncCallback<String>() {
				@Override
				public void onFailure(Throwable caught)
				{
					createSimpleDialog("OK", "Server Error", "An error occured while adding record").show();					
				}

				@Override
				public void onSuccess(String result) 
				{
					if (result != null)
					{
						final CustomDialogBox dialogBox = new CustomDialogBox();
						dialogBox.addButton("No", new ClickHandler() {							
							@Override
							public void onClick(ClickEvent event)
							{
								getHandlerManager().fireEvent(new CancelCreateEditProductEvent());
							}
						}).addButton("Yes", new ClickHandler() {						
							@Override
							public void onClick(ClickEvent event) 
							{							
								dialogBox.hide();
								view.getProductName().setValue("");
								view.getPrice().setValue("");
							}
						});
						dialogBox.addTitle("Insert Successful").addMessage("Do you wish to create another record?");						
						dialogBox.build().show();
					}
				}

			};
			getInventoryService().addProduct(product, addCallback);
		}
		
	}
	
	/**
	 * use the same view for create and update
	 * @author Gelo
	 *
	 */
	public interface Display extends DisplayView
	{
		/**
		 * multi-purpose button
		 * @return
		 */
		HasClickHandlers getAddUpdateButton();
		
		/**
		 * cancel update or add
		 * @return
		 */
		HasClickHandlers getCancelButton();
		
		/**
		 * the product name to add
		 * @return
		 */
		HasValue<String> getProductName();
		
		/**
		 * the price of the product to add
		 * @return
		 */
		HasValue<String> getPrice();
		
		/**
		 * Hidden Field, empty for add
		 * @return
		 */
		String getId();
	}	
}
